package com.snowfield.lbmonitor.serverStatus;

import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.snowfield.lb47.lbconfig.service.IBackserverService;
import com.snowfield.lb47.lbconfig.service.IFrontProxyService;
import com.snowfield.lbcommon.config.SnowFieldConfig;
import com.snowfield.lbcommon.utils.commonsexec.CommonExecutor;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * 后端服务器状态信息 Controller
 *
 * @author snowfield
 * @date 2024-04-22
 */
@RestController
@RequestMapping("/lbmonitor/serverStatus")
public class ServerStatusController extends BaseController {

    private static final Logger LOGGER = LoggerFactory.getLogger(ServerStatusController.class);

    @Autowired
    private IFrontProxyService frontProxyService;
    @Autowired
    private IBackserverService backserverService;

    /**
     * 获取后端服务器状态信息
     */
    @PreAuthorize("@ss.hasPermi('lbmonitor:serverStatus:list')")
    @GetMapping("/list")
    public AjaxResult serverStatus(HttpServletResponse response) {
        String shellFilePath = SnowFieldConfig.getBasicConfigPath() + "/serverStatus.sh";
        String resultFilePath = SnowFieldConfig.getBasicDataPath() + "/serverStatus.log";
        String shellContent = "echo 'show servers state' | socat stdio /var/run/haproxy.socket > " + resultFilePath + " 2>&1";

        HashMap<String, Object> resultData = new HashMap<>();
        try {
            File shellFile = new File(shellFilePath);
            if (!shellFile.exists()) {
                FileUtils.write(shellFile, shellContent, StandardCharsets.UTF_8);
            }

            String cmd = "sh";
            String[] args = {shellFilePath};
            CommonExecutor.execShell(cmd, args);

            File resultFile = new File(resultFilePath);

//            File testFile = new File("/data/snowfieldlb47/serverStatus.log");
//            FileUtils.copyFile(testFile, resultFile);
            if (resultFile.exists()) {
                resultData.put("code", HttpStatus.SUCCESS);
                //内容示例：
//                1
//                # be_id be_name srv_id srv_name srv_addr srv_op_state srv_admin_state 。。。。。。
//                3 proxy17 1 srv9 10.10.117.202 0 1 1 1 6 6 3 0 14 0 0 0 - 80 - 0 80 - - 80
//                3 proxy17 2 srv10 10.10.117.223 2 0 1 1 2128 6 3 5 6 0 0 0 - 80 - 0 80 - - 80
                List<String> contentList = FileUtils.readLines(resultFile, StandardCharsets.UTF_8);
                List<ServerStatusItem> itemList = new ArrayList<>();
                for (Integer idx = 0; idx < contentList.size(); idx++) {
                    //跳过第一，二行
                    if (idx.equals(0) || idx.equals(1)) {
                        continue;
                    }
                    //从第三行开始处理
                    String lineContent = contentList.get(idx);
                    if (StringUtils.isNotEmpty(lineContent)) {
                        String[] items = lineContent.split(" ");
                        if (items.length != 25) {
                            LOGGER.error("数据格式异常: {}", lineContent);
                            continue;
                        }
                        String beName = items[1];
                        String feName = beName;
                        Long proxyId = NumberUtils.toLong(beName.replace("proxy",""), 0L);
                        Long srvId = NumberUtils.toLong(items[3].replace("srv",""), 0L);
                        String srvAddr = items[4];
                        String srvOpState = items[5];
                        String srvAdminState = items[6];
                        String srvPort = items[18];
                        String srvCheckPort = items[21];

                        ServerStatusItem statusItem = new ServerStatusItem();
                        statusItem.setBeName(beName);
                        statusItem.setFeName(feName);
                        statusItem.setProxyId(proxyId);
                        statusItem.setSrvId(srvId);
                        statusItem.setSrvAddr(srvAddr);
                        statusItem.setSrvOpState(NumberUtils.toInt(srvOpState, -1));
                        statusItem.setSrvAdminState(NumberUtils.toInt(srvAdminState, -1));
                        statusItem.setSrvPort(NumberUtils.toInt(srvPort, -1));
                        statusItem.setSrvCheckPort(NumberUtils.toInt(srvCheckPort, -1));

                        itemList.add(statusItem);
                    }
                }

                resultData.put("rows", itemList);
            } else {
                resultData.put("code", HttpStatus.ERROR);
                resultData.put("rows", new ArrayList<>());
            }
        } catch (IOException ioException) {
            ioException.printStackTrace();
            resultData.put("code", HttpStatus.ERROR);
            resultData.put("rows", new ArrayList<>());
        }

        return AjaxResult.success(resultData);
    }

    /**
     * 返回前端代理Map信息，包括标识ID,代理名称
     */
    @PreAuthorize("@ss.hasPermi('lbmonitor:serverStatus:list')")
    @GetMapping("/frontProxySummaryMap")
    public AjaxResult frontProxySummaryMap() {
        return AjaxResult.success(frontProxyService.selectFrontProxySummary());
    }

    /**
     * 返回后端服务器概要信息
     */
    @PreAuthorize("@ss.hasPermi('lbmonitor:serverStatus:list')")
    @GetMapping("/serverSummaryMap")
    public AjaxResult serverSummaryMap() {
        return AjaxResult.success(backserverService.selectServerSummary());
    }
}
